use chrono::Datelike;
use dataforge::{generators::*, DataForge, Language};
use serde_json::json;

#[test]
fn test_forge_macro_basic() {
    let data = json!({
        "name": "测试用户",
        "age": 25,
        "active": true
    });

    assert_eq!(data["name"], "测试用户");
    assert_eq!(data["age"], 25);
    assert_eq!(data["active"], true);
}

#[test]
fn test_forge_macro_with_generators() {
    let data = json!({
        "id": uuid_v4(),
        "name": name::zh_cn_fullname(),
        "email": internet::email(),
        "age": 25
    });

    assert!(data["id"].is_string());
    assert!(data["name"].is_string());
    assert!(data["email"].is_string());
    assert!(data["age"].is_number());

    let age = data["age"].as_u64().unwrap();
    assert_eq!(age, 25);
}

#[test]
fn test_forge_macro_nested() {
    let data = json!({
        "user": {
            "profile": {
                "name": "测试用户",
                "age": 25
            },
            "contact": {
                "email": "test@example.com",
                "phone": "13800138000"
            }
        }
    });

    assert_eq!(data["user"]["profile"]["name"], "测试用户");
    assert_eq!(data["user"]["profile"]["age"], 25);
    assert_eq!(data["user"]["contact"]["email"], "test@example.com");
    assert_eq!(data["user"]["contact"]["phone"], "13800138000");
}

#[test]
fn test_dataforge_instance() {
    let forge = DataForge::new(Language::ZhCN);

    let uuid = forge.generate("uuid_v4");
    assert!(uuid.is_some());
    assert!(uuid.unwrap().is_string());

    let name = forge.generate("zh_cn_name");
    assert!(name.is_some());
    assert!(name.unwrap().is_string());
}

#[test]
fn test_dataforge_custom_generator() {
    let mut forge = DataForge::new(Language::ZhCN);

    forge.register("custom_test", || serde_json::json!("custom_value"));

    let result = forge.generate("custom_test");
    assert_eq!(result, Some(serde_json::json!("custom_value")));
}

#[test]
fn test_name_generators() {
    let zh_name = name::zh_cn_fullname();
    assert!(!zh_name.is_empty());
    assert!(zh_name.chars().count() >= 2);

    let en_name = name::en_us_fullname();
    assert!(!en_name.is_empty());
    assert!(en_name.contains(' '));

    let surname = name::zh_cn_surname();
    assert!(!surname.is_empty());

    let given_name = name::zh_cn_given_name();
    assert!(!given_name.is_empty());
}

#[test]
fn test_address_generators() {
    let province = address::zh_province();
    assert!(!province.is_empty());

    let city = address::zh_city();
    assert!(!city.is_empty());

    let street = address::zh_street();
    assert!(!street.is_empty());

    let full_address = address::zh_address();
    assert!(!full_address.is_empty());
    assert!(full_address.contains("号"));

    let postal_code = address::postal_code();
    assert_eq!(postal_code.len(), 6);
    assert!(postal_code.chars().all(|c| c.is_ascii_digit()));
}

#[test]
fn test_internet_generators() {
    let email = internet::email();
    assert!(email.contains('@'));
    assert!(email.contains('.'));

    let username = internet::username();
    assert!(!username.is_empty());
    assert!(username.len() >= 6);

    let password = internet::strong_password();
    assert!(password.len() >= 12);
    assert!(password.chars().any(|c| c.is_uppercase()));
    assert!(password.chars().any(|c| c.is_lowercase()));
    assert!(password.chars().any(|c| c.is_ascii_digit()));

    let ip = internet::ip_address();
    let parts: Vec<&str> = ip.split('.').collect();
    assert_eq!(parts.len(), 4);

    let mac = internet::mac_address();
    let parts: Vec<&str> = mac.split(':').collect();
    assert_eq!(parts.len(), 6);
}

#[test]
fn test_number_generators() {
    let age = number::adult_age();
    assert!(age >= 18 && age <= 80);

    let child_age = number::child_age();
    assert!(child_age >= 1 && child_age <= 17);

    let score = number::score();
    assert!(score <= 100);

    let phone = number::phone_number_cn();
    assert_eq!(phone.len(), 11);
    assert!(phone.starts_with('1'));

    let id_card = number::id_card_cn();
    assert_eq!(id_card.len(), 18);

    let credit_card = number::credit_card_number();
    assert_eq!(credit_card.len(), 16);
    assert!(credit_card.chars().all(|c| c.is_ascii_digit()));
}

#[test]
fn test_datetime_generators() {
    let birthday = datetime::birthday();
    let now = chrono::Utc::now();
    let age = now.year() - birthday.year();
    assert!(age >= 18 && age <= 80);

    let past = datetime::datetime_past_days(30);
    assert!(past < now);

    let future = datetime::datetime_future_days(30);
    assert!(future > now);

    let work_time = datetime::work_time();
    assert!(work_time.contains(':'));
    let parts: Vec<&str> = work_time.split(':').collect();
    assert_eq!(parts.len(), 2);

    let hour: u32 = parts[0].parse().unwrap();
    assert!(hour >= 9 && hour < 18);
}

#[test]
fn test_basic_generators() {
    let uuid = uuid_v4();
    assert_eq!(uuid.len(), 36);
    assert!(uuid.contains('-'));

    let int = random_int(1, 10);
    assert!(int >= 1 && int <= 10);

    let float = random_float(1.0, 2.0);
    assert!(float >= 1.0 && float <= 2.0);

    let bool_val = random_bool();
    assert!(bool_val == true || bool_val == false);

    let choices = ["a", "b", "c"];
    let choice = random_choice(&choices);
    assert!(choices.contains(&choice));
}

#[test]
fn test_batch_generation() {
    let users: Vec<_> = (0..100)
        .map(|i| {
            json!({
                "id": i,
                "name": name::zh_cn_fullname(),
                "email": internet::email(),
                "age": 25
            })
        })
        .collect();

    assert_eq!(users.len(), 100);

    for (i, user) in users.iter().enumerate() {
        assert_eq!(user["id"], i);
        assert!(user["name"].is_string());
        assert!(user["email"].is_string());
        assert!(user["age"].is_number());
    }
}

#[test]
fn test_parallel_generation() {
    use rayon::prelude::*;

    let users: Vec<_> = (0..1000)
        .into_par_iter()
        .map(|i| {
            json!({
                "id": i,
                "name": name::zh_cn_fullname(),
                "email": internet::email(),
                "phone": number::phone_number_cn()
            })
        })
        .collect();

    assert_eq!(users.len(), 1000);

    // 验证所有数据都是有效的
    for user in users {
        assert!(user["id"].is_number());
        assert!(user["name"].is_string());
        assert!(user["email"].as_str().unwrap().contains('@'));
        assert_eq!(user["phone"].as_str().unwrap().len(), 11);
    }
}

#[test]
fn test_macro_ranges() {
    // 测试多种范围语法
    for _ in 0..10 {
        let data = json!({
            "exclusive_range": random_int(1, 9),
            "inclusive_range": random_int(1, 10),
            "float_range": random_float(1.0, 2.0)
        });

        let exclusive = data["exclusive_range"].as_u64().unwrap();
        assert!(exclusive >= 1 && exclusive <= 9);

        let inclusive = data["inclusive_range"].as_u64().unwrap();
        assert!(inclusive >= 1 && inclusive <= 10);

        let float_val = data["float_range"].as_f64().unwrap();
        assert!(float_val >= 1.0 && float_val <= 2.0);
    }
}

#[test]
fn test_error_handling() {
    let forge = DataForge::new(Language::ZhCN);

    // 测试不存在的生成器
    let result = forge.generate("non_existent_generator");
    assert!(result.is_none());
}

#[cfg(feature = "database")]
#[test]
fn test_database_table_builder() {
    use dataforge::TableBuilder;

    let mut builder = TableBuilder::new("test_table".to_string());
    builder
        .field("id", || serde_json::json!(1))
        .field("name", || serde_json::json!("test"));

    let table = builder.build(100);
    assert_eq!(table.name, "test_table");
    assert_eq!(table.count, 100);
    assert_eq!(table.fields.len(), 2);
}

// ============================================================================
// 示例测试用例 (原examples文件夹内容转换)
// ============================================================================

#[test]
fn example_basic_usage() {
    println!("================================");

    // 1. 使用json!宏生成用户数据
    println!("\n1. 生成用户数据:");
    let user = json!({
        "id": uuid_v4(),
        "name": name::zh_cn_fullname(),
        "age": 25,
        "email": internet::email(),
        "phone": number::phone_number_cn(),
        "address": {
            "province": address::zh_province(),
            "city": address::zh_city(),
            "street": address::zh_street(),
            "postal_code": address::postal_code()
        },
        "profile": {
            "height": number::height_cm(),
            "weight": number::weight_kg(),
            "birthday": datetime::birthday().to_rfc3339(),
            "score": number::score()
        }
    });

    println!("{}", serde_json::to_string_pretty(&user).unwrap());

    // 验证数据结构
    assert!(user["id"].is_string());
    assert!(user["name"].is_string());
    assert_eq!(user["age"], 25);
    assert!(user["email"].is_string());
    assert!(user["phone"].is_string());
    assert!(user["address"]["province"].is_string());
    assert!(user["profile"]["height"].is_number());

    // 2. 使用DataForge实例
    println!("\n2. 使用DataForge实例:");
    let forge = DataForge::new(Language::ZhCN);

    if let Some(uuid) = forge.generate("uuid_v4") {
        println!("生成的UUID: {}", uuid);
        assert!(uuid.is_string());
    }

    if let Some(name) = forge.generate("zh_cn_name") {
        println!("生成的中文姓名: {}", name);
        assert!(name.is_string());
    }

    // 3. 直接调用生成器函数
    println!("\n3. 直接调用生成器函数:");
    let province = address::zh_province();
    let city = address::zh_city();
    let email = internet::email();
    let password = internet::strong_password();
    let ip = internet::ip_address();

    println!("随机省份: {}", province);
    println!("随机城市: {}", city);
    println!("随机邮箱: {}", email);
    println!("随机密码: {}", password);
    println!("随机IP地址: {}", ip);

    // 验证生成的数据
    assert!(!province.is_empty());
    assert!(!city.is_empty());
    assert!(email.contains('@'));
    assert!(password.len() >= 12);
    assert!(ip.split('.').count() == 4);

    // 4. 批量生成数据
    println!("\n4. 批量生成数据:");
    let users: Vec<_> = (0..5)
        .map(|i| {
            json!({
                "id": i + 1,
                "name": name::zh_cn_fullname(),
                "email": internet::email(),
                "age": random_int(20, 60),
                "salary": number::currency(5000.0, 25000.0),
                "department": random_choice(&["技术部", "市场部", "人事部", "财务部"])
            })
        })
        .collect();

    println!("批量生成的用户数据:");
    for user in &users {
        println!("  {}", serde_json::to_string(&user).unwrap());
    }

    // 验证批量数据
    assert_eq!(users.len(), 5);
    for (i, user) in users.iter().enumerate() {
        assert_eq!(user["id"], i + 1);
        assert!(user["name"].is_string());
        assert!(user["email"].is_string());
        assert!(user["age"].is_number());
        assert!(user["salary"].is_number());
        assert!(user["department"].is_string());
    }
}

#[test]
fn example_performance_test() {
    use rayon::prelude::*;
    use std::time::Instant;

    println!("DataForge 性能测试");
    println!("====================");

    // 单线程性能测试
    println!("\n1. 单线程性能测试:");
    let start = Instant::now();
    let single_thread_data: Vec<_> = (0..1_000)
        .map(|i| {
            json!({
                "id": i,
                "name": name::zh_cn_fullname(),
                "email": internet::email(),
                "phone": number::phone_number_cn(),
                "age": random_int(18, 65),
                "salary": number::currency(5000.0, 50000.0),
                "address": address::zh_address(),
                "created_at": datetime::iso8601()
            })
        })
        .collect();
    let single_duration = start.elapsed();

    println!(
        "生成 {} 条记录耗时: {:?}",
        single_thread_data.len(),
        single_duration
    );
    println!(
        "平均每条记录: {:?}",
        single_duration / single_thread_data.len() as u32
    );

    // 验证数据
    assert_eq!(single_thread_data.len(), 1_000);
    assert!(single_thread_data[0]["id"].is_number());
    assert!(single_thread_data[0]["name"].is_string());

    // 多线程性能测试
    println!("\n2. 多线程性能测试:");
    let start = Instant::now();
    let multi_thread_data: Vec<_> = (0..1_000)
        .into_par_iter()
        .map(|i| {
            json!({
                "id": i,
                "name": name::zh_cn_fullname(),
                "email": internet::email(),
                "phone": number::phone_number_cn(),
                "age": random_int(18, 65),
                "salary": number::currency(5000.0, 50000.0),
                "address": address::zh_address(),
                "created_at": datetime::iso8601()
            })
        })
        .collect();
    let multi_duration = start.elapsed();

    println!(
        "生成 {} 条记录耗时: {:?}",
        multi_thread_data.len(),
        multi_duration
    );
    println!(
        "平均每条记录: {:?}",
        multi_duration / multi_thread_data.len() as u32
    );

    // 验证数据
    assert_eq!(multi_thread_data.len(), 1_000);

    // 性能提升计算
    let speedup = single_duration.as_nanos() as f64 / multi_duration.as_nanos() as f64;
    println!("多线程性能提升: {:.2}x", speedup);
}

#[test]
fn example_custom_generators() {
    println!("==================");

    // 创建DataForge实例
    let mut forge = DataForge::new(Language::ZhCN);

    // 注册自定义生成器
    forge.register("custom_product_id", || {
        serde_json::json!(format!("PROD-{:06}", rand::random::<u32>() % 1000000))
    });

    forge.register("custom_order_status", || {
        let statuses = ["pending", "processing", "shipped", "delivered", "cancelled"];
        serde_json::json!(random_choice(&statuses))
    });

    forge.register("custom_price", || {
        serde_json::json!(number::currency(10.0, 999.99))
    });

    // 使用自定义生成器
    let product_id = forge.generate("custom_product_id").unwrap();
    let order_status = forge.generate("custom_order_status").unwrap();
    let price = forge.generate("custom_price").unwrap();

    println!("产品ID: {}", product_id);
    println!("订单状态: {}", order_status);
    println!("价格: {}", price);

    // 验证自定义生成器
    assert!(product_id.as_str().unwrap().starts_with("PROD-"));
    assert!(
        ["pending", "processing", "shipped", "delivered", "cancelled"]
            .contains(&order_status.as_str().unwrap())
    );
    assert!(price.is_number());
}

// ============================================================================
// 新功能模块测试
// ============================================================================

#[test]
fn test_core_engine_functionality() {
    use dataforge::{CoreEngine, GenConfig, GenerationStrategy};
    
    let config = GenConfig {
        batch_size: 100,
        locale: dataforge::Language::ZhCN,
        null_probability: 0.1,
        strategy: GenerationStrategy::Random,
        parallelism: 2,
    };
    
    let engine = CoreEngine::new(config);
    
    // 测试批量生成
    let result = engine.generate_batch(50);
    assert!(result.is_ok());
    
    let data = result.unwrap();
    assert_eq!(data.len(), 50);
    
    // 验证指标
    let metrics = engine.metrics();
    assert_eq!(metrics.generated_count(), 50);
    assert_eq!(metrics.error_count(), 0);
    
    // 测试Prometheus导出
    let prometheus_output = metrics.export_prometheus();
    assert!(prometheus_output.contains("dataforge_generated_total 50"));
}

#[test]
fn test_schema_parser_functionality() {
    use dataforge::{SchemaParser, DataType};
    use serde_json::json;
    
    let parser = SchemaParser::new();
    
    // 测试JSON Schema解析
    let json_schema = json!({
        "title": "TestTable",
        "type": "object",
        "properties": {
            "user_id": {
                "type": "integer"
            },
            "user_email": {
                "type": "string"
            },
            "user_phone": {
                "type": "string"
            },
            "created_at": {
                "type": "string"
            }
        }
    });
    
    let result = parser.infer_from_json(&json_schema);
    assert!(result.is_ok());
    
    let schema = result.unwrap();
    assert_eq!(schema.name, "TestTable");
    assert_eq!(schema.fields.len(), 4);
    
    // 验证字段类型推断
    let id_field = schema.fields.iter().find(|f| f.name == "user_id").unwrap();
    match &id_field.data_type {
        DataType::Integer { .. } => {},
        _ => panic!("Expected Integer type for user_id"),
    }
    
    let email_field = schema.fields.iter().find(|f| f.name == "user_email").unwrap();
    match &email_field.data_type {
        DataType::Email => {},
        _ => panic!("Expected Email type for user_email"),
    }
}

#[test]
fn test_memory_pool_functionality() {
    use dataforge::{MemoryPool, MemoryPoolConfig, StringPool};
    use std::time::Duration;
    
    // 测试内存池
    let config = MemoryPoolConfig {
        initial_size: 5,
        max_size: 20,
        size_classes: vec![64, 256, 1024],
        cleanup_interval: Duration::from_secs(1),
        max_idle_time: Duration::from_secs(5),
    };
    
    let pool = MemoryPool::new(config);
    
    // 测试分配和释放
    let buffer1 = pool.allocate(100);
    assert_eq!(buffer1.len(), 256); // 应该分配到256字节的size class
    
    let buffer2 = pool.allocate(500);
    assert_eq!(buffer2.len(), 1024); // 应该分配到1024字节的size class
    
    pool.deallocate(buffer1);
    pool.deallocate(buffer2);
    
    let stats = pool.stats();
    assert_eq!(stats.total_allocations, 2);
    assert_eq!(stats.total_deallocations, 2);
    
    // 测试字符串池
    let string_pool = StringPool::new(10);
    
    let s1 = string_pool.get_or_create("hello world");
    let s2 = string_pool.get_or_create("hello world");
    
    // 应该是同一个Arc实例
    assert!(std::sync::Arc::ptr_eq(&s1, &s2));
    
    let (cache_size, max_size) = string_pool.cache_info();
    assert_eq!(cache_size, 1);
    assert_eq!(max_size, 10);
}

#[test]
fn test_rule_engine_functionality() {
    use dataforge::{RuleEngine, Rule, RuleType, RuleContext};
    use std::collections::HashMap;
    
    let engine = RuleEngine::default();
    
    // 创建枚举规则
    let enum_rule = Rule {
        id: "status_rule".to_string(),
        name: "Status Rule".to_string(),
        rule_type: RuleType::Enum {
            values: vec![
                serde_json::Value::String("active".to_string()),
                serde_json::Value::String("inactive".to_string()),
                serde_json::Value::String("pending".to_string()),
            ],
        },
        priority: 100,
        enabled: true,
        description: Some("User status enumeration".to_string()),
        tags: vec!["status".to_string(), "user".to_string()],
        parent_id: None,
    };
    
    // 添加规则
    assert!(engine.add_rule(enum_rule).is_ok());
    
    // 创建范围规则
    let range_rule = Rule {
        id: "age_rule".to_string(),
        name: "Age Rule".to_string(),
        rule_type: RuleType::Range {
            min: serde_json::Value::Number(serde_json::Number::from(18)),
            max: serde_json::Value::Number(serde_json::Number::from(65)),
        },
        priority: 90,
        enabled: true,
        description: Some("Age range rule".to_string()),
        tags: vec!["age".to_string(), "user".to_string()],
        parent_id: None,
    };
    
    assert!(engine.add_rule(range_rule).is_ok());
    
    // 测试规则执行
    let context = RuleContext {
        field_name: "user_status".to_string(),
        current_value: None,
        params: HashMap::new(),
        generation_history: Vec::new(),
    };
    
    let result = engine.execute_rule("status_rule", &context);
    assert!(result.is_ok());
    
    let rule_result = result.unwrap();
    assert!(rule_result.matched);
    assert!(rule_result.value.is_some());
    
    if let Some(serde_json::Value::String(status)) = rule_result.value {
        assert!(["active", "inactive", "pending"].contains(&status.as_str()));
    }
    
    // 测试按标签查找规则
    let user_rules = engine.find_rules_by_tag("user");
    assert_eq!(user_rules.len(), 2);
}

#[test]
fn test_config_management() {
    use dataforge::{Config, ConfigManager, DatabaseConfig};
    use dataforge::config::OutputFormat;
    
    // 创建默认配置
    let mut config = Config::default();
    
    // 修改配置
    config.data_generation.batch_size = 2000;
    config.data_generation.null_probability = 0.15;
    config.data_generation.output_format = OutputFormat::Csv;
    
    // 添加数据库配置
    let db_config = DatabaseConfig {
        url: "postgresql://user:pass@localhost/testdb".to_string(),
        max_connections: 20,
        batch_insert_size: 5000,
        ..Default::default()
    };
    config.databases.insert("main".to_string(), db_config);
    
    // 创建配置管理器
    let manager = ConfigManager::new(config);
    
    // 验证配置
    assert!(manager.validate().is_ok());
    
    // 测试配置访问
    assert_eq!(manager.config().data_generation.batch_size, 2000);
    assert_eq!(manager.config().data_generation.null_probability, 0.15);
    
    let db_config = manager.get_database_config("main").unwrap();
    assert_eq!(db_config.url, "postgresql://user:pass@localhost/testdb");
    assert_eq!(db_config.max_connections, 20);
}

#[test]
fn test_integrated_workflow() {
    use dataforge::*;
    use std::sync::Arc;
    
    // 1. 创建内存池
    let memory_pool = Arc::new(MemoryPool::default());
    let string_pool = Arc::new(StringPool::default());
    
    // 2. 创建规则引擎
    let _rule_engine = RuleEngine::new(Arc::clone(&string_pool));
    
    // 3. 创建Schema解析器
    let _schema_parser = SchemaParser::new();
    
    // 4. 创建核心引擎
    let config = GenConfig {
        batch_size: 100,
        locale: Language::ZhCN,
        null_probability: 0.0,  // 设置为0以确保不生成null值
        strategy: GenerationStrategy::Random,
        parallelism: 2,
    };
    let core_engine = CoreEngine::new(config);
    
    // 5. 生成测试数据
    let result = core_engine.generate_batch(10);
    assert!(result.is_ok());
    
    let data = result.unwrap();
    assert_eq!(data.len(), 10);
    
    // 6. 验证生成的数据结构
    for item in &data {
        assert!(item.is_object());
        assert!(item["id"].is_number());
        assert!(item["uuid"].is_string());
        assert!(item["name"].is_string());
        assert!(item["email"].is_string());
        assert!(item["created_at"].is_string());
        assert!(item["metadata"].is_object());
    }
    
    // 7. 检查内存使用情况
    let memory_stats = memory_pool.stats();
    println!("内存统计: {:?}", memory_stats);
    
    // 8. 检查生成指标
    let metrics = core_engine.metrics();
    assert_eq!(metrics.generated_count(), 10);
    println!("生成指标: 总数={}, 错误={}", metrics.generated_count(), metrics.error_count());
}

#[test]
fn test_performance_with_new_modules() {
    use dataforge::*;
    use std::time::Instant;
    use rayon::prelude::*;
    
    let start = Instant::now();
    
    // 使用新的核心引擎进行大批量生成
    let config = GenConfig {
        batch_size: 1000,
        locale: Language::ZhCN,
        null_probability: 0.02,
        strategy: GenerationStrategy::Random,
        parallelism: 4,
    };
    
    let engine = CoreEngine::new(config);
    
    // 并行生成多个批次
    let batches: Vec<_> = (0..10).into_par_iter().map(|_| {
        engine.generate_batch(1000)
    }).collect();
    
    let duration = start.elapsed();
    
    // 验证结果
    let mut total_records = 0;
    for batch_result in batches {
        assert!(batch_result.is_ok());
        total_records += batch_result.unwrap().len();
    }
    
    assert_eq!(total_records, 10000);
    
    let throughput = total_records as f64 / duration.as_secs_f64();
    println!("生成了 {} 条记录，耗时 {:?}", total_records, duration);
    println!("吞吐量: {:.0} 记录/秒", throughput);
    
    // 验证指标
    let metrics = engine.metrics();
    assert_eq!(metrics.generated_count(), 10000);
}